knitr::opts_chunk$set(echo = TRUE, warning = FALSE, message = FALSE, cache = FALSE)

Setup for analysis

Load packages

library(tidyverse) # tidy style coding
library(brms) # Bayesian models
library(loo) # to use information criteria in brms models
library(tidybayes) # Bayesian aesthetics
library(MetBrewer) # colours
library(kableExtra) # tables
library(patchwork) # putting plots together
library(DT) # for search- and saveable tables
library(pander) # for simpler tables

Load in the data

\(~\)

fitness_data <- read_csv("data/SLC_fitness_data.csv") %>% 
  mutate(Fitness_vial_ID = as.factor(Fitness_vial_ID),
         Block = as.factor(Block),
         Population = as.factor(Population),
         Treatment = as.factor(Treatment),
         GFP = as.factor(GFP),
         Sex = as.factor(Sex),
         Rearing_vial = as.factor(Rearing_vial),
         Sex = as.factor(Sex),
         Total_red_offspring = Red_female_offspring + Red_male_offspring,
         Total_bw_offspring = bw_female_offspring + bw_male_offspring,
         Total_offspring = Total_red_offspring + Total_bw_offspring)

# Create a function to build HTML searchable tables

my_data_table <- function(df){
  datatable(
    df, rownames=FALSE,
    autoHideNavigation = TRUE,
    extensions = c("Scroller",  "Buttons"),
    options = list(
      dom = 'Bfrtip',
      deferRender=TRUE,
      scrollX=TRUE, scrollY=400,
      scrollCollapse=TRUE,
      buttons =
        list('pageLength', 'colvis', 'csv', list(
          extend = 'pdf',
          pageSize = 'A4',
          orientation = 'landscape',
          filename = 'fitness_data')),
      pageLength = 692
    )
  )
}


my_data_table(fitness_data %>% select(-Comment))

Column explanations

\(~\)

Fitness_vial_ID: a unique identifier for each replicate of the fitness assays.

Block: the experiment was run in three distinct blocks, using flies from separate generations.

Population: we measured the fitness of flies from 12 independent populations that has undergone experimental evolution.

Treatment: the populations had been exposed to one of three evolutionary conditions for 20 generations: a female-limited response to selection, a male-limited response and a control condition where the evolutionary response was unconstrained.

GFP: the GFP marker carried by the population. UBI indicates the presence of a transgene that encodes ubiquitous expression of GFP, while 3xP indicates the presence of a different transgene that encodes the expression of GFP in the ocelli.

Sex: the sex of the individuals that we were measuring the fitness of.

Rearing_vial: the vial the flies developed in. This variable is included to capture variation explained by the rearing environment e.g. small differences in food moisture content or quantity. Note that females and males can have the same rearing vial.

Red_female_offspring: the number of adult female offspring sired/produced by flies sourced from one of the 12 populations.

Red_male_offspring: the number of adult male offspring sired/produced by flies sourced from one of the 12 populations.

bw_female_offspring: the number of adult female offspring sired/produced by the competitor flies in our fitness assay. bw is a recessive allele that encodes brown eye colour.

bw_male_offspring: the number of adult male offspring sired/produced by the competitor flies in our fitness assay. bw is a recessive allele that encodes brown eye colour.

Total_red_offspring: the total number (sexes pooled) of adult offspring sired/produced by flies sourced from one of the 12 populations.

Total_bw_offspring: the total number (sexes pooled) of adult offspring sired/produced by competitor flies.

Total_offspring: the total number (sexes and eye colours pooled) of adult offspring counted in each vial.

\(~\)

Modelling approach

\(~\)

Female and male fitness are fundamentally different concepts / traits. Therefore, we choose to split the data up and model them separately.

female_fitness <- 
  fitness_data %>%
  filter(Sex == "Female")

male_fitness <- 
  fitness_data %>%
  filter(Sex == "Male")

Note that, while the female and male fitness assays are very similar, they do differ. The major difference is that the male assay contains half the number of females in any given vial than does the female assay. The logic behind this design choice is that sexual selection is a more important part of male fitness than it is female fitness, so any fitness differences may only be observed when competition for fertilisations is high.

Playing devils advocate with my chosen approach: one reason why we might want to keep all the data together is that the Rearing_vial variable is shared between the fitness datasets. That is, females included in the female fitness assay developed alongside males that were included in the male fitness assay. Keeping the data as one therefore gives us greater power for estimating the effect of rearing vial on fitness.

Variables we can include in our models

Block and Rearing_vial: technically, Rearing_vial can be nested inside Block. Both explain variation in the data caused by the way we designed our experiment. We have greater power to estimate block effects, because the number of fitness assays conducted within a block is much larger than the number of fitness assays conducted per rearing vial. However, the block effect might miss fine scale variance that might be important to account for. Blocks also contain data from all GFP and evolution treatment levels, while rearing vials only contain flies from specific populations and GFP types.

GFP: it is possible that fitness may be affected by the GFP transgene carried by each population. For example, one could imagine that any unintended fitness effects of a transgene might be of greater magnitude if it is expressed in a larger proportion of tissues, as is the case for the UBI transgene versus the 3xP transgene.

Treatment: this is the evolution treatment that populations were subject to for 20 generations. There are three levels: populations carrying female-adapted chromosomes, populations containing male-adapted chromosomes and populations carrying control chromosomes that have experienced an unlimited response to selection. This variable is central to our hypothesis.

Population: our design contained 12 independent populations that originated from a single outbred laboratory population. The populations were split and each was subjected to one of the three evolution treatments for 20 generations. 4 populations experienced a female-limited response to selection, 4 a male-limited response and 4 an unlimited response.

\(~\)

Female fitness

\(~\)

To estimate the fitness of females carrying each of the three chromosome types, we placed three experimental females into a yeasted vial with three female competitors that carried the bw mutation. We then introduced six males that also carried the bw mutation. We allowed them to mate and oviposit for three days, then removed all adults from the vial. 12 days later we counted all of the adult progeny in the vial and scored them for eye-colour. Progeny with red eyes were produced by the experimental females ( bw is recessive) and progeny with brown eyes were produced by the competitor females. We calculated fitness as the proportion of red eyed offspring in the vial.

\(~\)

Let’s start with a simple model. We’ll specify the binomial family, set priors and include Rearing_vial as a random effect. This simply accounts for potential sources of variance stemming from the way we designed our fly lines and our fitness assays. While they are not interesting per se in regards to our hypothesis, they need to be accounted for, as they may mask an effect of the variables we are principally investigating.

female_fitness.01 <-
  brm(Total_red_offspring | trials(Total_offspring) ~ 1 + (1|Rearing_vial),
      data = female_fitness, family = binomial(), 
      prior = c(prior(normal(0, 1.5), class = Intercept),
                #prior(normal(0, 2), class = b),
                prior(exponential(1), class = sd)),
      iter = 6000, warmup = 2000, chains = 4, cores = 4,
      control = list(adapt_delta = 0.9, max_treedepth = 10),
      seed = 2, file = "Fits/female_fitness.01")

#add_criterion(female_fitness.01, criterion = "waic")

To see if we’re on the right track with our model, let’s perform a posterior predictive check. From our model we predict values and build a distribution. If the shape of the distribution matches the raw data reasonably well, we can be confident that we have specified an appropriate error distribution.

pp_check(female_fitness.01, type = "hist", ndraws = 11, binwidth = 10) +
  theme_minimal() +
  theme(panel.background = element_blank())

Now we can visualise our predictions for each rearing vial.

# get draws from the posterior distribution

draws <- as_draws_df(female_fitness.01)

# wrangle the data to get relevant predictions

draws_rearing_vials <- 
  coef(female_fitness.01, robust = T)$Rearing_vial[, , ] %>% 
  as_tibble(rownames = NA) %>% 
  rownames_to_column("Rearing_vial") %>% 
  mutate(Estimate = inv_logit_scaled(Estimate),
         Q2.5 = inv_logit_scaled(Q2.5),
         Q97.5 = inv_logit_scaled(Q97.5)) %>% 
  select(Rearing_vial, Estimate, Q2.5, Q97.5) %>% 
  mutate_at(2:4, round, 3)

# combine with raw data 

draws_rearing_vials <-
  full_join(draws_rearing_vials, female_fitness %>% distinct(Rearing_vial, .keep_all = TRUE) %>% 
  select(Block, Population, Treatment, GFP, Rearing_vial))

# plot the variation between rearing vials for fitness, including block and GFP effects 

draws_rearing_vials %>% mutate(Rearing_vial = as.numeric(Rearing_vial)) %>% 
  ggplot(aes(x = Rearing_vial)) +
  geom_hline(yintercept = inv_logit_scaled(median(draws$b_Intercept)), linetype = 2, size = 1/2) +
  geom_vline(xintercept = c(24.5, 48.5), size = 1/3, color = "grey25") +
  geom_point(aes(y = Estimate, fill = GFP), shape = 21, size = 3) +
  annotate(geom = "text", 
           x = c(12, 36, 60), y = 0.4, 
           label = c("Block 1", "Block 2", "Block 3")) +
  scale_fill_manual(values=c("grey", "green")) +
  scale_x_continuous(breaks = NULL) +
  scale_y_continuous(breaks = c(0.5, 0.75, 1), limits = c(0.35, 1)) +
  labs(y = "Fitness",
       x = NULL) +
  theme_bw() +
  theme(panel.grid.major = element_blank())

Figure 1: there is an exploratory Figure that I’ll cut from our final analysis…

Note that populations carrying the 3xP GFP transgene appear to have higher fitness than those carrying the Ubi GFP transgene. Furthermore, Block 1 fitness measures appear to be higher than those in Blocks 2 or 3.

\(~\)

The full model

Now lets add in the fixed effects:

  • Treatment

  • GFP

  • Block

The model below is good, but it’s missing the Population variable.

female_fitness.02 <-
  brm(Total_red_offspring | trials(Total_offspring) ~ 1 + Treatment + GFP + Block + (1|Rearing_vial),
      data = female_fitness, family = binomial(), 
      prior = c(prior(normal(0, 1.5), class = Intercept),
                prior(normal(0, 2), class = b),
                prior(exponential(1), class = sd)),
      iter = 6000, warmup = 2000, chains = 4, cores = 4,
      control = list(adapt_delta = 0.9, max_treedepth = 10),
      seed = 2, file = "Fits/female_fitness.02")

#add_criterion(female_fitness.02, criterion = "waic")

print(female_fitness.02)
##  Family: binomial 
##   Links: mu = logit 
## Formula: Total_red_offspring | trials(Total_offspring) ~ 1 + Treatment + GFP + Block + (1 | Rearing_vial) 
##    Data: female_fitness (Number of observations: 327) 
##   Draws: 4 chains, each with iter = 6000; warmup = 2000; thin = 1;
##          total post-warmup draws = 16000
## 
## Group-Level Effects: 
## ~Rearing_vial (Number of levels: 70) 
##               Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## sd(Intercept)     0.27      0.03     0.22     0.33 1.00     3856     5981
## 
## Population-Level Effects: 
##                         Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS
## Intercept                   1.10      0.08     0.93     1.26 1.00     3966
## TreatmentFemale_limited     0.19      0.08     0.03     0.36 1.00     3793
## TreatmentMale_limited       0.16      0.08     0.00     0.32 1.00     3869
## GFPUBI                     -0.32      0.07    -0.45    -0.19 1.00     4325
## Block2                     -0.59      0.08    -0.75    -0.42 1.00     4231
## Block3                     -0.61      0.08    -0.77    -0.45 1.00     3804
##                         Tail_ESS
## Intercept                   6101
## TreatmentFemale_limited     6285
## TreatmentMale_limited       6584
## GFPUBI                      5765
## Block2                      7216
## Block3                      6205
## 
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).

Provisionally, it appears that after accounting for the effect of GFP and the residual variance caused by block and vial effects, female fitness is higher when sex-limited inheritance occurs, regardless of the sex that is being limited…

\(~\)

Get predictions from the model and present them in a Table

draws <- as_draws_df(female_fitness.02)

draws_female <-
  draws  %>% 
  mutate(`Female-limited` = inv_logit_scaled(b_Intercept + b_TreatmentFemale_limited),
         `Male-limited` = inv_logit_scaled(b_Intercept + b_TreatmentMale_limited),
         Control = inv_logit_scaled(b_Intercept)) %>% 
  select(Control, `Female-limited`, `Male-limited`) %>% 
    pivot_longer(cols = c(Control, `Female-limited`, `Male-limited`),
                 names_to = "Treatment") %>% 
  rename(prop_focal_offspring = value)

draws_female %>% 
  group_by(Treatment) %>% 
  summarise(`Estimated prop. of offspring produced` = median(prop_focal_offspring),
            `2.5%` = quantile(prop_focal_offspring, probs = 0.025),
            `97.5%` = quantile(prop_focal_offspring, probs = 0.975)) %>% 
  rename(`Evolution treatment` = Treatment) %>% 
  pander(split.cell = 40, split.table = Inf, round = 3)
Evolution treatment Estimated prop. of offspring produced 2.5% 97.5%
Control 0.75 0.717 0.778
Female-limited 0.784 0.755 0.811
Male-limited 0.779 0.75 0.805
# now find the differences between the control and the sex-limited treatments

# the inv_logit_scaled() function converts the posterior draws onto the response scale 

  draws %>% 
  mutate(p_control =  inv_logit_scaled(b_Intercept),
         p_female = inv_logit_scaled(b_TreatmentFemale_limited + b_Intercept),
         p_male = inv_logit_scaled(b_TreatmentMale_limited + b_Intercept),
         `Female-limited` = p_female / p_control,
         `Male-limited` = p_male / p_control) %>% 
  gather(key = `difference comparison`, value = `% difference`) %>% 
  filter(`difference comparison` == c("Female-limited", "Male-limited")) %>% 
  group_by(`difference comparison`)  %>% 
  summarise(`Mean proportion of offspring produced relative to control`  = mean(`% difference`),
            `2.5%` = quantile(`% difference`, probs = 0.025),
            `97.5%` = quantile(`% difference`, probs = 0.975)) %>% 
  rename(`Evolution treatment` = `difference comparison`) %>% 
  pander(split.cell = 40, split.table = Inf, round = 3)
Evolution treatment Mean proportion of offspring produced relative to control 2.5% 97.5%
Female-limited 1.046 1.006 1.088
Male-limited 1.039 1 1.081

Lets plot our findings

# plot
f_1 <-
  draws_female %>% 
  ggplot(aes(Treatment, prop_focal_offspring)) + 
  stat_eye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 1) + # width indicates the uncertainty intervals: here we have 66% and 95% intervals
  scale_fill_manual(values = met.brewer("Hiroshige", 3)) +
  scale_y_continuous("Female fitness\n(proportion of offspring produced)",
                     breaks = c(0.6, 0.7, 0.8, 0.9)) +
  xlab("Evolutionary history") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank())

f_2 <-
  draws %>% 
  mutate(`Female-limited` = b_TreatmentFemale_limited,
         `Male-limited` = b_TreatmentMale_limited) %>% 
  gather(key = parameter, value = logodds) %>% 
  filter(parameter == c("Female-limited", "Male-limited")) %>%
  as_tibble() %>% 
  
  ggplot(aes(parameter, logodds)) + 
  stat_halfeye(aes(fill = parameter), .width = c(0.66, 0.95)) + # width indicates the uncertainty intervals: here we have 66% and 95% intervals
  scale_fill_manual(values = c("Female-limited" = "#ffd06f", "Male-limited" = "#72bcd5")) + 
  coord_flip() +
  geom_hline(yintercept = 0, linetype = 2) +
  #scale_y_continuous(breaks = c(-4, -2, 0, 2)) +
  xlab(NULL) +
  ylab("Log-odds difference from control") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank())

f_1 + f_2

Figure 2: chromosomes with sex-limited inheritance have higher fitness in females than chromosomes with unconstrained inheritance.

\(~\)

Male fitness

\(~\)

To estimate the fitness of males carrying each of the three chromosome types, we conducted an experiment very similar to the female fitness assay. However, because male fitness has stronger covariance with fertilisation events than does female fitness, we conducted the male fitness assay with a 1:2 sex ratio (female:male) rather than the 1:1 ratio used in the female assay. This increases the strength of sexual selection and is a more appopriate way to expose differences in fitness between groups of males. As with the females, we calculated fitness as the proportion of red eyed offspring in the vial.

\(~\)

Let’s once again start with a simple model. We’ll specify the binomial family, set priors and include Rearing_vial as a random effect, just as we did for the female data.

male_fitness.01 <-
  brm(Total_red_offspring | trials(Total_offspring) ~ 1 + (1|Rearing_vial),
      data = male_fitness, family = binomial(), 
      prior = c(prior(normal(0, 1.5), class = Intercept),
                #prior(normal(0, 2), class = b),
                prior(exponential(1), class = sd)),
      iter = 10000, warmup = 2000, chains = 4, cores = 4,
      control = list(adapt_delta = 0.95, max_treedepth = 10),
      seed = 2, file = "Fits/male_fitness.01")

#add_criterion(male_fitness.01, criterion = "waic")

Conduct the posterior predictive check…

pp_check(male_fitness.01, type = "hist", ndraws = 11, binwidth = 10) +
  theme_minimal() +
  theme(panel.background = element_blank())

Now we can visualise our predictions for each rearing vial.

# get draws from the posterior distribution

draws_m <- as_draws_df(male_fitness.01)

# wrangle the data to get relevant predictions

draws_rearing_vials_m <- 
  coef(male_fitness.01, robust = T)$Rearing_vial[, , ] %>% 
  as_tibble(rownames = NA) %>% 
  rownames_to_column("Rearing_vial") %>% 
  mutate(Estimate = inv_logit_scaled(Estimate),
         Q2.5 = inv_logit_scaled(Q2.5),
         Q97.5 = inv_logit_scaled(Q97.5)) %>% 
  select(Rearing_vial, Estimate, Q2.5, Q97.5) %>% 
  mutate_at(2:4, round, 3)

# combine with raw data 

draws_rearing_vials_m <-
  full_join(draws_rearing_vials_m, male_fitness %>% distinct(Rearing_vial, .keep_all = TRUE) %>% 
  select(Block, Population, Treatment, GFP, Rearing_vial))

# plot the variation between rearing vials for fitness, including block and GFP effects 

draws_rearing_vials_m %>% 
  mutate(Rearing_vial = as.numeric(Rearing_vial)) %>% 
  ggplot(aes(x = Rearing_vial)) +
  geom_hline(yintercept = inv_logit_scaled(median(draws$b_Intercept)), linetype = 2, size = 1/2) +
  geom_vline(xintercept = c(24.5, 48.5), size = 1/3, color = "grey25") +
  geom_point(aes(y = Estimate, fill = GFP), shape = 21, size = 3) +
  annotate(geom = "text", 
           x = c(12, 36, 60), y = 0.4, 
           label = c("Block 1", "Block 2", "Block 3")) +
  scale_fill_manual(values=c("grey", "green")) +
  scale_x_continuous(breaks = NULL) +
  scale_y_continuous(breaks = c(0.5, 0.75, 1), limits = c(0.35, 1)) +
  labs(y = "Fitness",
       x = NULL) +
  theme_bw() +
  theme(panel.grid.major = element_blank())

Whether there is a difference in fitness between the two GFP transgenes is not as clear this time. However, we once again see differences in fitness between Blocks, with Block 2 looking to have higher fitness measures than 1 or 3.

\(~\)

The full model

Now lets add in the fixed effects:

  • Treatment

  • GFP

  • Block

The model below is good, but it’s missing the Population variable.

male_fitness.02 <-
  brm(Total_red_offspring | trials(Total_offspring) ~ 1 + Treatment + GFP + Block + (1|Rearing_vial),
      data = male_fitness, family = binomial(), 
      prior = c(prior(normal(0, 1.5), class = Intercept),
                prior(normal(0, 2), class = b),
                prior(exponential(1), class = sd)),
      iter = 10000, warmup = 2000, chains = 4, cores = 4,
      control = list(adapt_delta = 0.95, max_treedepth = 10),
      seed = 2, file = "Fits/male_fitness.02")

#add_criterion(male_fitness.02, criterion = "waic")

print(male_fitness.02)
##  Family: binomial 
##   Links: mu = logit 
## Formula: Total_red_offspring | trials(Total_offspring) ~ 1 + Treatment + GFP + Block + (1 | Rearing_vial) 
##    Data: male_fitness (Number of observations: 360) 
##   Draws: 4 chains, each with iter = 10000; warmup = 2000; thin = 1;
##          total post-warmup draws = 32000
## 
## Group-Level Effects: 
## ~Rearing_vial (Number of levels: 72) 
##               Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## sd(Intercept)     0.65      0.07     0.54     0.79 1.00     3286     5222
## 
## Population-Level Effects: 
##                         Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS
## Intercept                   0.61      0.19     0.23     0.97 1.00     2301
## TreatmentFemale_limited     0.05      0.18    -0.30     0.40 1.00     2554
## TreatmentMale_limited       0.34      0.18    -0.01     0.70 1.00     2458
## GFPUBI                      0.03      0.14    -0.24     0.31 1.00     2873
## Block2                      0.93      0.19     0.55     1.30 1.00     2562
## Block3                      0.05      0.19    -0.31     0.43 1.00     2394
##                         Tail_ESS
## Intercept                   3882
## TreatmentFemale_limited     4886
## TreatmentMale_limited       4087
## GFPUBI                      5029
## Block2                      4704
## Block3                      3613
## 
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).

This time, we have evidence to suggest that male-adapted chromosomes produce high fitness males, but that female-adaptted chromosomes produce males with the same fitness as do control chromosomes.

\(~\)

Get predictions from the model and present them in a Table

draws_m <- as_draws_df(male_fitness.02)

draws_male <-
  draws_m  %>% 
  mutate(`Female-limited` = inv_logit_scaled(b_Intercept + b_TreatmentFemale_limited),
         `Male-limited` = inv_logit_scaled(b_Intercept + b_TreatmentMale_limited),
         Control = inv_logit_scaled(b_Intercept)) %>% 
  select(Control, `Female-limited`, `Male-limited`) %>% 
    pivot_longer(cols = c(Control, `Female-limited`, `Male-limited`),
                 names_to = "Treatment") %>% 
  rename(prop_focal_offspring = value)

draws_male %>% 
  group_by(Treatment) %>% 
  summarise(`Estimated prop. of offspring sired` = median(prop_focal_offspring),
            `2.5%` = quantile(prop_focal_offspring, probs = 0.025),
            `97.5%` = quantile(prop_focal_offspring, probs = 0.975)) %>% 
  rename(`Evolution treatment` = Treatment) %>% 
  pander(split.cell = 40, split.table = Inf, round = 3)
Evolution treatment Estimated prop. of offspring sired 2.5% 97.5%
Control 0.648 0.558 0.725
Female-limited 0.66 0.582 0.726
Male-limited 0.721 0.642 0.789
# now find the differences between the control and the sex-limited treatments

# the inv_logit_scaled() function converts the posterior draws onto the response scale 

  draws_m %>% 
  mutate(p_control =  inv_logit_scaled(b_Intercept),
         p_female = inv_logit_scaled(b_TreatmentFemale_limited + b_Intercept),
         p_male = inv_logit_scaled(b_TreatmentMale_limited + b_Intercept),
         `Female-limited` = p_female / p_control,
         `Male-limited` = p_male / p_control) %>% 
  gather(key = `difference comparison`, value = `% difference`) %>% 
  filter(`difference comparison` == c("Female-limited", "Male-limited")) %>% 
  group_by(`difference comparison`)  %>% 
  summarise(`Mean proportion of offspring sired relative to control`  = mean(`% difference`),
            `2.5%` = quantile(`% difference`, probs = 0.025),
            `97.5%` = quantile(`% difference`, probs = 0.975)) %>% 
  rename(`Evolution treatment` = `difference comparison`) %>% 
  pander(split.cell = 40, split.table = Inf, round = 3)
Evolution treatment Mean proportion of offspring sired relative to control 2.5% 97.5%
Female-limited 1.022 0.902 1.158
Male-limited 1.115 0.996 1.258

Lets plot our findings

# plot
f_3 <-
  draws_male %>% 
  ggplot(aes(Treatment, prop_focal_offspring)) + 
  stat_eye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 1) + # width indicates the uncertainty intervals: here we have 66% and 95% intervals
  scale_fill_manual(values = met.brewer("Hiroshige", 3)) +
  scale_y_continuous("Male fitness\n(proportion of offspring sired)",
                     breaks = c(0.6, 0.7, 0.8, 0.9)) +
  xlab("Evolutionary history") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        axis.text.x = element_text(angle = 45, vjust = 1, hjust=1))

f_4 <-
  draws_m %>% 
  mutate(`Female-limited` = b_TreatmentFemale_limited,
         `Male-limited` = b_TreatmentMale_limited) %>% 
  gather(key = parameter, value = logodds) %>% 
  filter(parameter == c("Female-limited", "Male-limited")) %>%
  as_tibble() %>% 
  #mutate(parameter =factor(parameter, levels=c("SD-Mad", "SD-72", "SD-5"))) %>%
  
  ggplot(aes(parameter, logodds)) + 
  stat_halfeye(aes(fill = parameter), .width = c(0.66, 0.95)) + # width indicates the uncertainty intervals: here we have 66% and 95% intervals
  scale_fill_manual(values = c("Female-limited" = "#ffd06f", "Male-limited" = "#72bcd5")) + 
  coord_flip() +
  geom_hline(yintercept = 0, linetype = 2) +
  #scale_y_continuous(breaks = c(-4, -2, 0, 2)) +
  xlab(NULL) +
  ylab("Log-odds difference from control") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank())

f_3 + f_4

Figure 3: chromosomes with male-limited inheritance have higher fitness in males than chromosomes with unconstrained or female-limited inheritance.

LS0tDQp0aXRsZTogIkV4cGVyaW1lbnRhbCBlbmZvcmNlbWVudCBvZiBzZXgtbGltaXRlZCBhZGFwdGF0aW9uIg0KYXV0aG9yOiAiVGhvbWFzIEtlYW5leSINCiNiaWJsaW9ncmFwaHk6ICJzdXBwX3JlZmVyZW5jZXMuYmliIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGRlcHRoOiAxDQogICAgbnVtYmVyX3NlY3Rpb25zOiBubw0KICAgIHRoZW1lOiB5ZXRpDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCmVkaXRvcl9vcHRpb25zOg0KICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQ0KLS0tDQoNCg0KDQpgYGB7cn0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UsIGNhY2hlID0gRkFMU0UpDQpgYGANCg0KIyBTZXR1cCBmb3IgYW5hbHlzaXMNCg0KIyMgTG9hZCBwYWNrYWdlcw0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKSAjIHRpZHkgc3R5bGUgY29kaW5nDQpsaWJyYXJ5KGJybXMpICMgQmF5ZXNpYW4gbW9kZWxzDQpsaWJyYXJ5KGxvbykgIyB0byB1c2UgaW5mb3JtYXRpb24gY3JpdGVyaWEgaW4gYnJtcyBtb2RlbHMNCmxpYnJhcnkodGlkeWJheWVzKSAjIEJheWVzaWFuIGFlc3RoZXRpY3MNCmxpYnJhcnkoTWV0QnJld2VyKSAjIGNvbG91cnMNCmxpYnJhcnkoa2FibGVFeHRyYSkgIyB0YWJsZXMNCmxpYnJhcnkocGF0Y2h3b3JrKSAjIHB1dHRpbmcgcGxvdHMgdG9nZXRoZXINCmxpYnJhcnkoRFQpICMgZm9yIHNlYXJjaC0gYW5kIHNhdmVhYmxlIHRhYmxlcw0KbGlicmFyeShwYW5kZXIpICMgZm9yIHNpbXBsZXIgdGFibGVzDQpgYGANCg0KIyMgTG9hZCBpbiB0aGUgZGF0YSANCg0KJH4kDQoNCmBgYHtyfQ0KDQpmaXRuZXNzX2RhdGEgPC0gcmVhZF9jc3YoImRhdGEvU0xDX2ZpdG5lc3NfZGF0YS5jc3YiKSAlPiUgDQogIG11dGF0ZShGaXRuZXNzX3ZpYWxfSUQgPSBhcy5mYWN0b3IoRml0bmVzc192aWFsX0lEKSwNCiAgICAgICAgIEJsb2NrID0gYXMuZmFjdG9yKEJsb2NrKSwNCiAgICAgICAgIFBvcHVsYXRpb24gPSBhcy5mYWN0b3IoUG9wdWxhdGlvbiksDQogICAgICAgICBUcmVhdG1lbnQgPSBhcy5mYWN0b3IoVHJlYXRtZW50KSwNCiAgICAgICAgIEdGUCA9IGFzLmZhY3RvcihHRlApLA0KICAgICAgICAgU2V4ID0gYXMuZmFjdG9yKFNleCksDQogICAgICAgICBSZWFyaW5nX3ZpYWwgPSBhcy5mYWN0b3IoUmVhcmluZ192aWFsKSwNCiAgICAgICAgIFNleCA9IGFzLmZhY3RvcihTZXgpLA0KICAgICAgICAgVG90YWxfcmVkX29mZnNwcmluZyA9IFJlZF9mZW1hbGVfb2Zmc3ByaW5nICsgUmVkX21hbGVfb2Zmc3ByaW5nLA0KICAgICAgICAgVG90YWxfYndfb2Zmc3ByaW5nID0gYndfZmVtYWxlX29mZnNwcmluZyArIGJ3X21hbGVfb2Zmc3ByaW5nLA0KICAgICAgICAgVG90YWxfb2Zmc3ByaW5nID0gVG90YWxfcmVkX29mZnNwcmluZyArIFRvdGFsX2J3X29mZnNwcmluZykNCg0KIyBDcmVhdGUgYSBmdW5jdGlvbiB0byBidWlsZCBIVE1MIHNlYXJjaGFibGUgdGFibGVzDQoNCm15X2RhdGFfdGFibGUgPC0gZnVuY3Rpb24oZGYpew0KICBkYXRhdGFibGUoDQogICAgZGYsIHJvd25hbWVzPUZBTFNFLA0KICAgIGF1dG9IaWRlTmF2aWdhdGlvbiA9IFRSVUUsDQogICAgZXh0ZW5zaW9ucyA9IGMoIlNjcm9sbGVyIiwgICJCdXR0b25zIiksDQogICAgb3B0aW9ucyA9IGxpc3QoDQogICAgICBkb20gPSAnQmZydGlwJywNCiAgICAgIGRlZmVyUmVuZGVyPVRSVUUsDQogICAgICBzY3JvbGxYPVRSVUUsIHNjcm9sbFk9NDAwLA0KICAgICAgc2Nyb2xsQ29sbGFwc2U9VFJVRSwNCiAgICAgIGJ1dHRvbnMgPQ0KICAgICAgICBsaXN0KCdwYWdlTGVuZ3RoJywgJ2NvbHZpcycsICdjc3YnLCBsaXN0KA0KICAgICAgICAgIGV4dGVuZCA9ICdwZGYnLA0KICAgICAgICAgIHBhZ2VTaXplID0gJ0E0JywNCiAgICAgICAgICBvcmllbnRhdGlvbiA9ICdsYW5kc2NhcGUnLA0KICAgICAgICAgIGZpbGVuYW1lID0gJ2ZpdG5lc3NfZGF0YScpKSwNCiAgICAgIHBhZ2VMZW5ndGggPSA2OTINCiAgICApDQogICkNCn0NCg0KDQpteV9kYXRhX3RhYmxlKGZpdG5lc3NfZGF0YSAlPiUgc2VsZWN0KC1Db21tZW50KSkNCg0KYGBgDQoNCioqQ29sdW1uIGV4cGxhbmF0aW9ucyoqDQoNCiR+JA0KDQpGaXRuZXNzX3ZpYWxfSUQ6IGEgdW5pcXVlIGlkZW50aWZpZXIgZm9yIGVhY2ggcmVwbGljYXRlIG9mIHRoZSBmaXRuZXNzIGFzc2F5cy4NCg0KQmxvY2s6IHRoZSBleHBlcmltZW50IHdhcyBydW4gaW4gdGhyZWUgZGlzdGluY3QgYmxvY2tzLCB1c2luZyBmbGllcyBmcm9tIHNlcGFyYXRlIGdlbmVyYXRpb25zLg0KDQpQb3B1bGF0aW9uOiB3ZSBtZWFzdXJlZCB0aGUgZml0bmVzcyBvZiBmbGllcyBmcm9tIDEyIGluZGVwZW5kZW50IHBvcHVsYXRpb25zIHRoYXQgaGFzIHVuZGVyZ29uZSBleHBlcmltZW50YWwgZXZvbHV0aW9uLg0KDQpUcmVhdG1lbnQ6IHRoZSBwb3B1bGF0aW9ucyBoYWQgYmVlbiBleHBvc2VkIHRvIG9uZSBvZiB0aHJlZSBldm9sdXRpb25hcnkgY29uZGl0aW9ucyBmb3IgMjAgZ2VuZXJhdGlvbnM6IGEgZmVtYWxlLWxpbWl0ZWQgcmVzcG9uc2UgdG8gc2VsZWN0aW9uLCBhIG1hbGUtbGltaXRlZCByZXNwb25zZSBhbmQgYSBjb250cm9sIGNvbmRpdGlvbiB3aGVyZSB0aGUgZXZvbHV0aW9uYXJ5IHJlc3BvbnNlIHdhcyB1bmNvbnN0cmFpbmVkLg0KDQpHRlA6IHRoZSBHRlAgbWFya2VyIGNhcnJpZWQgYnkgdGhlIHBvcHVsYXRpb24uIFVCSSBpbmRpY2F0ZXMgdGhlIHByZXNlbmNlIG9mIGEgdHJhbnNnZW5lIHRoYXQgZW5jb2RlcyB1YmlxdWl0b3VzIGV4cHJlc3Npb24gb2YgR0ZQLCB3aGlsZSAzeFAgaW5kaWNhdGVzIHRoZSBwcmVzZW5jZSBvZiBhIGRpZmZlcmVudCB0cmFuc2dlbmUgdGhhdCBlbmNvZGVzIHRoZSBleHByZXNzaW9uIG9mIEdGUCBpbiB0aGUgb2NlbGxpLiANCg0KU2V4OiB0aGUgc2V4IG9mIHRoZSBpbmRpdmlkdWFscyB0aGF0IHdlIHdlcmUgbWVhc3VyaW5nIHRoZSBmaXRuZXNzIG9mLg0KDQpSZWFyaW5nX3ZpYWw6IHRoZSB2aWFsIHRoZSBmbGllcyBkZXZlbG9wZWQgaW4uIFRoaXMgdmFyaWFibGUgaXMgaW5jbHVkZWQgdG8gY2FwdHVyZSB2YXJpYXRpb24gZXhwbGFpbmVkIGJ5IHRoZSByZWFyaW5nIGVudmlyb25tZW50IGUuZy4gc21hbGwgZGlmZmVyZW5jZXMgaW4gZm9vZCBtb2lzdHVyZSBjb250ZW50IG9yIHF1YW50aXR5LiBOb3RlIHRoYXQgZmVtYWxlcyBhbmQgbWFsZXMgY2FuIGhhdmUgdGhlIHNhbWUgcmVhcmluZyB2aWFsLg0KDQpSZWRfZmVtYWxlX29mZnNwcmluZzogdGhlIG51bWJlciBvZiBhZHVsdCBmZW1hbGUgb2Zmc3ByaW5nIHNpcmVkL3Byb2R1Y2VkIGJ5IGZsaWVzIHNvdXJjZWQgZnJvbSBvbmUgb2YgdGhlIDEyIHBvcHVsYXRpb25zLg0KDQpSZWRfbWFsZV9vZmZzcHJpbmc6IHRoZSBudW1iZXIgb2YgYWR1bHQgbWFsZSBvZmZzcHJpbmcgc2lyZWQvcHJvZHVjZWQgYnkgZmxpZXMgc291cmNlZCBmcm9tIG9uZSBvZiB0aGUgMTIgcG9wdWxhdGlvbnMuDQoNCmJ3X2ZlbWFsZV9vZmZzcHJpbmc6IHRoZSBudW1iZXIgb2YgYWR1bHQgZmVtYWxlIG9mZnNwcmluZyBzaXJlZC9wcm9kdWNlZCBieSB0aGUgY29tcGV0aXRvciBmbGllcyBpbiBvdXIgZml0bmVzcyBhc3NheS4gX2J3XyBpcyBhIHJlY2Vzc2l2ZSBhbGxlbGUgdGhhdCBlbmNvZGVzIGJyb3duIGV5ZSBjb2xvdXIuDQoNCmJ3X21hbGVfb2Zmc3ByaW5nOiB0aGUgbnVtYmVyIG9mIGFkdWx0IG1hbGUgb2Zmc3ByaW5nIHNpcmVkL3Byb2R1Y2VkIGJ5IHRoZSBjb21wZXRpdG9yIGZsaWVzIGluIG91ciBmaXRuZXNzIGFzc2F5LiBfYndfIGlzIGEgcmVjZXNzaXZlIGFsbGVsZSB0aGF0IGVuY29kZXMgYnJvd24gZXllIGNvbG91ci4NCg0KVG90YWxfcmVkX29mZnNwcmluZzogdGhlIHRvdGFsIG51bWJlciAoc2V4ZXMgcG9vbGVkKSBvZiBhZHVsdCBvZmZzcHJpbmcgc2lyZWQvcHJvZHVjZWQgYnkgZmxpZXMgc291cmNlZCBmcm9tIG9uZSBvZiB0aGUgMTIgcG9wdWxhdGlvbnMuDQoNClRvdGFsX2J3X29mZnNwcmluZzogdGhlIHRvdGFsIG51bWJlciAoc2V4ZXMgcG9vbGVkKSBvZiBhZHVsdCBvZmZzcHJpbmcgc2lyZWQvcHJvZHVjZWQgYnkgY29tcGV0aXRvciBmbGllcy4NCg0KVG90YWxfb2Zmc3ByaW5nOiB0aGUgdG90YWwgbnVtYmVyIChzZXhlcyBhbmQgZXllIGNvbG91cnMgcG9vbGVkKSBvZiBhZHVsdCBvZmZzcHJpbmcgY291bnRlZCBpbiBlYWNoIHZpYWwuDQoNCg0KJH4kDQoNCiMgTW9kZWxsaW5nIGFwcHJvYWNoDQoNCiR+JA0KDQpGZW1hbGUgYW5kIG1hbGUgZml0bmVzcyBhcmUgZnVuZGFtZW50YWxseSBkaWZmZXJlbnQgY29uY2VwdHMgLyB0cmFpdHMuIFRoZXJlZm9yZSwgd2UgY2hvb3NlIHRvIHNwbGl0IHRoZSBkYXRhIHVwIGFuZCBtb2RlbCB0aGVtIHNlcGFyYXRlbHkuDQoNCmBgYHtyfQ0KZmVtYWxlX2ZpdG5lc3MgPC0gDQogIGZpdG5lc3NfZGF0YSAlPiUNCiAgZmlsdGVyKFNleCA9PSAiRmVtYWxlIikNCg0KbWFsZV9maXRuZXNzIDwtIA0KICBmaXRuZXNzX2RhdGEgJT4lDQogIGZpbHRlcihTZXggPT0gIk1hbGUiKQ0KICANCmBgYA0KDQoNCk5vdGUgdGhhdCwgd2hpbGUgdGhlIGZlbWFsZSBhbmQgbWFsZSBmaXRuZXNzIGFzc2F5cyBhcmUgdmVyeSBzaW1pbGFyLCB0aGV5IGRvIGRpZmZlci4gVGhlIG1ham9yIGRpZmZlcmVuY2UgaXMgdGhhdCB0aGUgbWFsZSBhc3NheSBjb250YWlucyBoYWxmIHRoZSBudW1iZXIgb2YgZmVtYWxlcyBpbiBhbnkgZ2l2ZW4gdmlhbCB0aGFuIGRvZXMgdGhlIGZlbWFsZSBhc3NheS4gVGhlIGxvZ2ljIGJlaGluZCB0aGlzIGRlc2lnbiBjaG9pY2UgaXMgdGhhdCBzZXh1YWwgc2VsZWN0aW9uIGlzIGEgbW9yZSBpbXBvcnRhbnQgcGFydCBvZiBtYWxlIGZpdG5lc3MgdGhhbiBpdCBpcyBmZW1hbGUgZml0bmVzcywgc28gYW55IGZpdG5lc3MgZGlmZmVyZW5jZXMgbWF5IG9ubHkgYmUgb2JzZXJ2ZWQgd2hlbiBjb21wZXRpdGlvbiBmb3IgZmVydGlsaXNhdGlvbnMgaXMgaGlnaC4NCg0KKipQbGF5aW5nIGRldmlscyBhZHZvY2F0ZSB3aXRoIG15IGNob3NlbiBhcHByb2FjaCoqOiBvbmUgcmVhc29uIHdoeSB3ZSBtaWdodCB3YW50IHRvIGtlZXAgYWxsIHRoZSBkYXRhIHRvZ2V0aGVyIGlzIHRoYXQgdGhlIGBSZWFyaW5nX3ZpYWxgIHZhcmlhYmxlIGlzIHNoYXJlZCBiZXR3ZWVuIHRoZSBmaXRuZXNzIGRhdGFzZXRzLiBUaGF0IGlzLCBmZW1hbGVzIGluY2x1ZGVkIGluIHRoZSBmZW1hbGUgZml0bmVzcyBhc3NheSBkZXZlbG9wZWQgYWxvbmdzaWRlIG1hbGVzIHRoYXQgd2VyZSBpbmNsdWRlZCBpbiB0aGUgbWFsZSBmaXRuZXNzIGFzc2F5LiBLZWVwaW5nIHRoZSBkYXRhIGFzIG9uZSB0aGVyZWZvcmUgZ2l2ZXMgdXMgZ3JlYXRlciBwb3dlciBmb3IgZXN0aW1hdGluZyB0aGUgZWZmZWN0IG9mIHJlYXJpbmcgdmlhbCBvbiBmaXRuZXNzLiANCg0KKipWYXJpYWJsZXMgd2UgY2FuIGluY2x1ZGUgaW4gb3VyIG1vZGVscyoqDQoNCmBCbG9ja2AgYW5kIGBSZWFyaW5nX3ZpYWxgOiB0ZWNobmljYWxseSwgYFJlYXJpbmdfdmlhbGAgY2FuIGJlIG5lc3RlZCBpbnNpZGUgYEJsb2NrYC4gQm90aCBleHBsYWluIHZhcmlhdGlvbiBpbiB0aGUgZGF0YSBjYXVzZWQgYnkgdGhlIHdheSB3ZSBkZXNpZ25lZCBvdXIgZXhwZXJpbWVudC4gV2UgaGF2ZSBncmVhdGVyIHBvd2VyIHRvIGVzdGltYXRlIGJsb2NrIGVmZmVjdHMsIGJlY2F1c2UgdGhlIG51bWJlciBvZiBmaXRuZXNzIGFzc2F5cyBjb25kdWN0ZWQgd2l0aGluIGEgYmxvY2sgaXMgbXVjaCBsYXJnZXIgdGhhbiB0aGUgbnVtYmVyIG9mIGZpdG5lc3MgYXNzYXlzIGNvbmR1Y3RlZCBwZXIgcmVhcmluZyB2aWFsLiBIb3dldmVyLCB0aGUgYmxvY2sgZWZmZWN0IG1pZ2h0IG1pc3MgZmluZSBzY2FsZSB2YXJpYW5jZSB0aGF0IG1pZ2h0IGJlIGltcG9ydGFudCB0byBhY2NvdW50IGZvci4gQmxvY2tzIGFsc28gY29udGFpbiBkYXRhIGZyb20gYWxsIEdGUCBhbmQgZXZvbHV0aW9uIHRyZWF0bWVudCBsZXZlbHMsIHdoaWxlIHJlYXJpbmcgdmlhbHMgb25seSBjb250YWluIGZsaWVzIGZyb20gc3BlY2lmaWMgcG9wdWxhdGlvbnMgYW5kIEdGUCB0eXBlcy4NCg0KYEdGUGA6IGl0IGlzIHBvc3NpYmxlIHRoYXQgZml0bmVzcyBtYXkgYmUgYWZmZWN0ZWQgYnkgdGhlIEdGUCB0cmFuc2dlbmUgY2FycmllZCBieSBlYWNoIHBvcHVsYXRpb24uIEZvciBleGFtcGxlLCBvbmUgY291bGQgaW1hZ2luZSB0aGF0IGFueSB1bmludGVuZGVkIGZpdG5lc3MgZWZmZWN0cyBvZiBhIHRyYW5zZ2VuZSBtaWdodCBiZSBvZiBncmVhdGVyIG1hZ25pdHVkZSBpZiBpdCBpcyBleHByZXNzZWQgaW4gYSBsYXJnZXIgcHJvcG9ydGlvbiBvZiB0aXNzdWVzLCBhcyBpcyB0aGUgY2FzZSBmb3IgdGhlIF9VQklfIHRyYW5zZ2VuZSB2ZXJzdXMgdGhlIF8zeFBfIHRyYW5zZ2VuZS4NCg0KYFRyZWF0bWVudGA6IHRoaXMgaXMgdGhlIGV2b2x1dGlvbiB0cmVhdG1lbnQgdGhhdCBwb3B1bGF0aW9ucyB3ZXJlIHN1YmplY3QgdG8gZm9yIDIwIGdlbmVyYXRpb25zLiBUaGVyZSBhcmUgdGhyZWUgbGV2ZWxzOiBwb3B1bGF0aW9ucyBjYXJyeWluZyBmZW1hbGUtYWRhcHRlZCBjaHJvbW9zb21lcywgcG9wdWxhdGlvbnMgY29udGFpbmluZyBtYWxlLWFkYXB0ZWQgY2hyb21vc29tZXMgYW5kIHBvcHVsYXRpb25zIGNhcnJ5aW5nIGNvbnRyb2wgY2hyb21vc29tZXMgdGhhdCBoYXZlIGV4cGVyaWVuY2VkIGFuIHVubGltaXRlZCByZXNwb25zZSB0byBzZWxlY3Rpb24uIFRoaXMgdmFyaWFibGUgaXMgY2VudHJhbCB0byBvdXIgaHlwb3RoZXNpcy4NCg0KYFBvcHVsYXRpb25gOiBvdXIgZGVzaWduIGNvbnRhaW5lZCAxMiBpbmRlcGVuZGVudCBwb3B1bGF0aW9ucyB0aGF0IG9yaWdpbmF0ZWQgZnJvbSBhIHNpbmdsZSBvdXRicmVkIGxhYm9yYXRvcnkgcG9wdWxhdGlvbi4gVGhlIHBvcHVsYXRpb25zIHdlcmUgc3BsaXQgYW5kIGVhY2ggd2FzIHN1YmplY3RlZCB0byBvbmUgb2YgdGhlIHRocmVlIGV2b2x1dGlvbiB0cmVhdG1lbnRzIGZvciAyMCBnZW5lcmF0aW9ucy4gNCBwb3B1bGF0aW9ucyBleHBlcmllbmNlZCBhIGZlbWFsZS1saW1pdGVkIHJlc3BvbnNlIHRvIHNlbGVjdGlvbiwgNCBhIG1hbGUtbGltaXRlZCByZXNwb25zZSBhbmQgNCBhbiB1bmxpbWl0ZWQgcmVzcG9uc2UuIA0KDQokfiQNCg0KIyBGZW1hbGUgZml0bmVzcw0KDQokfiQNCg0KVG8gZXN0aW1hdGUgdGhlIGZpdG5lc3Mgb2YgZmVtYWxlcyBjYXJyeWluZyBlYWNoIG9mIHRoZSB0aHJlZSBjaHJvbW9zb21lIHR5cGVzLCB3ZSBwbGFjZWQgdGhyZWUgZXhwZXJpbWVudGFsIGZlbWFsZXMgaW50byBhIHllYXN0ZWQgdmlhbCB3aXRoIHRocmVlIGZlbWFsZSBjb21wZXRpdG9ycyB0aGF0IGNhcnJpZWQgdGhlIF9id18gbXV0YXRpb24uIFdlIHRoZW4gaW50cm9kdWNlZCBzaXggbWFsZXMgdGhhdCBhbHNvIGNhcnJpZWQgdGhlIF9id18gbXV0YXRpb24uIFdlIGFsbG93ZWQgdGhlbSB0byBtYXRlIGFuZCBvdmlwb3NpdCBmb3IgdGhyZWUgZGF5cywgdGhlbiByZW1vdmVkIGFsbCBhZHVsdHMgZnJvbSB0aGUgdmlhbC4gMTIgZGF5cyBsYXRlciB3ZSBjb3VudGVkIGFsbCBvZiB0aGUgYWR1bHQgcHJvZ2VueSBpbiB0aGUgdmlhbCBhbmQgc2NvcmVkIHRoZW0gZm9yIGV5ZS1jb2xvdXIuIFByb2dlbnkgd2l0aCByZWQgZXllcyB3ZXJlIHByb2R1Y2VkIGJ5IHRoZSBleHBlcmltZW50YWwgZmVtYWxlcyAoIF9id18gaXMgcmVjZXNzaXZlKSBhbmQgcHJvZ2VueSB3aXRoIGJyb3duIGV5ZXMgd2VyZSBwcm9kdWNlZCBieSB0aGUgY29tcGV0aXRvciBmZW1hbGVzLiBXZSBjYWxjdWxhdGVkIGZpdG5lc3MgYXMgdGhlIHByb3BvcnRpb24gb2YgcmVkIGV5ZWQgb2Zmc3ByaW5nIGluIHRoZSB2aWFsLiANCg0KJH4kDQoNCkxldCdzIHN0YXJ0IHdpdGggYSBzaW1wbGUgbW9kZWwuIFdlJ2xsIHNwZWNpZnkgdGhlIGJpbm9taWFsIGZhbWlseSwgc2V0IHByaW9ycyBhbmQgaW5jbHVkZSBgUmVhcmluZ192aWFsYCBhcyBhIHJhbmRvbSBlZmZlY3QuIFRoaXMgc2ltcGx5IGFjY291bnRzIGZvciBwb3RlbnRpYWwgc291cmNlcyBvZiB2YXJpYW5jZSBzdGVtbWluZyBmcm9tIHRoZSB3YXkgd2UgZGVzaWduZWQgb3VyIGZseSBsaW5lcyBhbmQgb3VyIGZpdG5lc3MgYXNzYXlzLiBXaGlsZSB0aGV5IGFyZSBub3QgaW50ZXJlc3RpbmcgcGVyIHNlIGluIHJlZ2FyZHMgdG8gb3VyIGh5cG90aGVzaXMsIHRoZXkgbmVlZCB0byBiZSBhY2NvdW50ZWQgZm9yLCBhcyB0aGV5IG1heSBtYXNrIGFuIGVmZmVjdCBvZiB0aGUgdmFyaWFibGVzIHdlIGFyZSBwcmluY2lwYWxseSBpbnZlc3RpZ2F0aW5nLg0KDQpgYGB7cn0NCmZlbWFsZV9maXRuZXNzLjAxIDwtDQogIGJybShUb3RhbF9yZWRfb2Zmc3ByaW5nIHwgdHJpYWxzKFRvdGFsX29mZnNwcmluZykgfiAxICsgKDF8UmVhcmluZ192aWFsKSwNCiAgICAgIGRhdGEgPSBmZW1hbGVfZml0bmVzcywgZmFtaWx5ID0gYmlub21pYWwoKSwgDQogICAgICBwcmlvciA9IGMocHJpb3Iobm9ybWFsKDAsIDEuNSksIGNsYXNzID0gSW50ZXJjZXB0KSwNCiAgICAgICAgICAgICAgICAjcHJpb3Iobm9ybWFsKDAsIDIpLCBjbGFzcyA9IGIpLA0KICAgICAgICAgICAgICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9IHNkKSksDQogICAgICBpdGVyID0gNjAwMCwgd2FybXVwID0gMjAwMCwgY2hhaW5zID0gNCwgY29yZXMgPSA0LA0KICAgICAgY29udHJvbCA9IGxpc3QoYWRhcHRfZGVsdGEgPSAwLjksIG1heF90cmVlZGVwdGggPSAxMCksDQogICAgICBzZWVkID0gMiwgZmlsZSA9ICJGaXRzL2ZlbWFsZV9maXRuZXNzLjAxIikNCg0KI2FkZF9jcml0ZXJpb24oZmVtYWxlX2ZpdG5lc3MuMDEsIGNyaXRlcmlvbiA9ICJ3YWljIikNCg0KYGBgDQoNClRvIHNlZSBpZiB3ZSdyZSBvbiB0aGUgcmlnaHQgdHJhY2sgd2l0aCBvdXIgbW9kZWwsIGxldCdzIHBlcmZvcm0gYSBwb3N0ZXJpb3IgcHJlZGljdGl2ZSBjaGVjay4gRnJvbSBvdXIgbW9kZWwgd2UgcHJlZGljdCB2YWx1ZXMgYW5kIGJ1aWxkIGEgZGlzdHJpYnV0aW9uLiBJZiB0aGUgc2hhcGUgb2YgdGhlIGRpc3RyaWJ1dGlvbiBtYXRjaGVzIHRoZSByYXcgZGF0YSByZWFzb25hYmx5IHdlbGwsIHdlIGNhbiBiZSBjb25maWRlbnQgdGhhdCB3ZSBoYXZlIHNwZWNpZmllZCBhbiBhcHByb3ByaWF0ZSBlcnJvciBkaXN0cmlidXRpb24uDQoNCmBgYHtyfQ0KcHBfY2hlY2soZmVtYWxlX2ZpdG5lc3MuMDEsIHR5cGUgPSAiaGlzdCIsIG5kcmF3cyA9IDExLCBiaW53aWR0aCA9IDEwKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCkpDQpgYGANCg0KTm93IHdlIGNhbiB2aXN1YWxpc2Ugb3VyIHByZWRpY3Rpb25zIGZvciBlYWNoIHJlYXJpbmcgdmlhbC4NCg0KYGBge3J9DQoNCiMgZ2V0IGRyYXdzIGZyb20gdGhlIHBvc3RlcmlvciBkaXN0cmlidXRpb24NCg0KZHJhd3MgPC0gYXNfZHJhd3NfZGYoZmVtYWxlX2ZpdG5lc3MuMDEpDQoNCiMgd3JhbmdsZSB0aGUgZGF0YSB0byBnZXQgcmVsZXZhbnQgcHJlZGljdGlvbnMNCg0KZHJhd3NfcmVhcmluZ192aWFscyA8LSANCiAgY29lZihmZW1hbGVfZml0bmVzcy4wMSwgcm9idXN0ID0gVCkkUmVhcmluZ192aWFsWywgLCBdICU+JSANCiAgYXNfdGliYmxlKHJvd25hbWVzID0gTkEpICU+JSANCiAgcm93bmFtZXNfdG9fY29sdW1uKCJSZWFyaW5nX3ZpYWwiKSAlPiUgDQogIG11dGF0ZShFc3RpbWF0ZSA9IGludl9sb2dpdF9zY2FsZWQoRXN0aW1hdGUpLA0KICAgICAgICAgUTIuNSA9IGludl9sb2dpdF9zY2FsZWQoUTIuNSksDQogICAgICAgICBROTcuNSA9IGludl9sb2dpdF9zY2FsZWQoUTk3LjUpKSAlPiUgDQogIHNlbGVjdChSZWFyaW5nX3ZpYWwsIEVzdGltYXRlLCBRMi41LCBROTcuNSkgJT4lIA0KICBtdXRhdGVfYXQoMjo0LCByb3VuZCwgMykNCg0KIyBjb21iaW5lIHdpdGggcmF3IGRhdGEgDQoNCmRyYXdzX3JlYXJpbmdfdmlhbHMgPC0NCiAgZnVsbF9qb2luKGRyYXdzX3JlYXJpbmdfdmlhbHMsIGZlbWFsZV9maXRuZXNzICU+JSBkaXN0aW5jdChSZWFyaW5nX3ZpYWwsIC5rZWVwX2FsbCA9IFRSVUUpICU+JSANCiAgc2VsZWN0KEJsb2NrLCBQb3B1bGF0aW9uLCBUcmVhdG1lbnQsIEdGUCwgUmVhcmluZ192aWFsKSkNCg0KIyBwbG90IHRoZSB2YXJpYXRpb24gYmV0d2VlbiByZWFyaW5nIHZpYWxzIGZvciBmaXRuZXNzLCBpbmNsdWRpbmcgYmxvY2sgYW5kIEdGUCBlZmZlY3RzIA0KDQpkcmF3c19yZWFyaW5nX3ZpYWxzICU+JSBtdXRhdGUoUmVhcmluZ192aWFsID0gYXMubnVtZXJpYyhSZWFyaW5nX3ZpYWwpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IFJlYXJpbmdfdmlhbCkpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gaW52X2xvZ2l0X3NjYWxlZChtZWRpYW4oZHJhd3MkYl9JbnRlcmNlcHQpKSwgbGluZXR5cGUgPSAyLCBzaXplID0gMS8yKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGMoMjQuNSwgNDguNSksIHNpemUgPSAxLzMsIGNvbG9yID0gImdyZXkyNSIpICsNCiAgZ2VvbV9wb2ludChhZXMoeSA9IEVzdGltYXRlLCBmaWxsID0gR0ZQKSwgc2hhcGUgPSAyMSwgc2l6ZSA9IDMpICsNCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgDQogICAgICAgICAgIHggPSBjKDEyLCAzNiwgNjApLCB5ID0gMC40LCANCiAgICAgICAgICAgbGFiZWwgPSBjKCJCbG9jayAxIiwgIkJsb2NrIDIiLCAiQmxvY2sgMyIpKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJncmV5IiwgImdyZWVuIikpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IE5VTEwpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMC41LCAwLjc1LCAxKSwgbGltaXRzID0gYygwLjM1LCAxKSkgKw0KICBsYWJzKHkgPSAiRml0bmVzcyIsDQogICAgICAgeCA9IE5VTEwpICsNCiAgdGhlbWVfYncoKSArDQogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCkpDQpgYGANCg0KKipGaWd1cmUgMSoqOiB0aGVyZSBpcyBhbiBleHBsb3JhdG9yeSBGaWd1cmUgdGhhdCBJJ2xsIGN1dCBmcm9tIG91ciBmaW5hbCBhbmFseXNpcy4uLg0KDQpOb3RlIHRoYXQgcG9wdWxhdGlvbnMgY2FycnlpbmcgdGhlIDN4UCBHRlAgdHJhbnNnZW5lIGFwcGVhciB0byBoYXZlIGhpZ2hlciBmaXRuZXNzIHRoYW4gdGhvc2UgY2FycnlpbmcgdGhlIFViaSBHRlAgdHJhbnNnZW5lLiBGdXJ0aGVybW9yZSwgQmxvY2sgMSBmaXRuZXNzIG1lYXN1cmVzIGFwcGVhciB0byBiZSBoaWdoZXIgdGhhbiB0aG9zZSBpbiBCbG9ja3MgMiBvciAzLg0KDQokfiQNCg0KKipUaGUgZnVsbCBtb2RlbCoqDQoNCk5vdyBsZXRzIGFkZCBpbiB0aGUgZml4ZWQgZWZmZWN0czoNCg0KLSBUcmVhdG1lbnQNCg0KLSBHRlANCg0KLSBCbG9jaw0KDQpUaGUgbW9kZWwgYmVsb3cgaXMgZ29vZCwgYnV0IGl0J3MgbWlzc2luZyB0aGUgYFBvcHVsYXRpb25gIHZhcmlhYmxlLg0KDQpgYGB7cn0NCmZlbWFsZV9maXRuZXNzLjAyIDwtDQogIGJybShUb3RhbF9yZWRfb2Zmc3ByaW5nIHwgdHJpYWxzKFRvdGFsX29mZnNwcmluZykgfiAxICsgVHJlYXRtZW50ICsgR0ZQICsgQmxvY2sgKyAoMXxSZWFyaW5nX3ZpYWwpLA0KICAgICAgZGF0YSA9IGZlbWFsZV9maXRuZXNzLCBmYW1pbHkgPSBiaW5vbWlhbCgpLCANCiAgICAgIHByaW9yID0gYyhwcmlvcihub3JtYWwoMCwgMS41KSwgY2xhc3MgPSBJbnRlcmNlcHQpLA0KICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLCAyKSwgY2xhc3MgPSBiKSwNCiAgICAgICAgICAgICAgICBwcmlvcihleHBvbmVudGlhbCgxKSwgY2xhc3MgPSBzZCkpLA0KICAgICAgaXRlciA9IDYwMDAsIHdhcm11cCA9IDIwMDAsIGNoYWlucyA9IDQsIGNvcmVzID0gNCwNCiAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45LCBtYXhfdHJlZWRlcHRoID0gMTApLA0KICAgICAgc2VlZCA9IDIsIGZpbGUgPSAiRml0cy9mZW1hbGVfZml0bmVzcy4wMiIpDQoNCiNhZGRfY3JpdGVyaW9uKGZlbWFsZV9maXRuZXNzLjAyLCBjcml0ZXJpb24gPSAid2FpYyIpDQoNCnByaW50KGZlbWFsZV9maXRuZXNzLjAyKQ0KYGBgDQoNClByb3Zpc2lvbmFsbHksIGl0IGFwcGVhcnMgdGhhdCBhZnRlciBhY2NvdW50aW5nIGZvciB0aGUgZWZmZWN0IG9mIEdGUCBhbmQgdGhlIHJlc2lkdWFsIHZhcmlhbmNlIGNhdXNlZCBieSBibG9jayBhbmQgdmlhbCBlZmZlY3RzLCBmZW1hbGUgZml0bmVzcyBpcyBoaWdoZXIgd2hlbiBzZXgtbGltaXRlZCBpbmhlcml0YW5jZSBvY2N1cnMsIHJlZ2FyZGxlc3Mgb2YgdGhlIHNleCB0aGF0IGlzIGJlaW5nIGxpbWl0ZWQuLi4NCg0KJH4kDQoNCkdldCBwcmVkaWN0aW9ucyBmcm9tIHRoZSBtb2RlbCBhbmQgcHJlc2VudCB0aGVtIGluIGEgVGFibGUNCg0KYGBge3J9DQoNCmRyYXdzIDwtIGFzX2RyYXdzX2RmKGZlbWFsZV9maXRuZXNzLjAyKQ0KDQpkcmF3c19mZW1hbGUgPC0NCiAgZHJhd3MgICU+JSANCiAgbXV0YXRlKGBGZW1hbGUtbGltaXRlZGAgPSBpbnZfbG9naXRfc2NhbGVkKGJfSW50ZXJjZXB0ICsgYl9UcmVhdG1lbnRGZW1hbGVfbGltaXRlZCksDQogICAgICAgICBgTWFsZS1saW1pdGVkYCA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQgKyBiX1RyZWF0bWVudE1hbGVfbGltaXRlZCksDQogICAgICAgICBDb250cm9sID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCkpICU+JSANCiAgc2VsZWN0KENvbnRyb2wsIGBGZW1hbGUtbGltaXRlZGAsIGBNYWxlLWxpbWl0ZWRgKSAlPiUgDQogICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKENvbnRyb2wsIGBGZW1hbGUtbGltaXRlZGAsIGBNYWxlLWxpbWl0ZWRgKSwNCiAgICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiVHJlYXRtZW50IikgJT4lIA0KICByZW5hbWUocHJvcF9mb2NhbF9vZmZzcHJpbmcgPSB2YWx1ZSkNCg0KZHJhd3NfZmVtYWxlICU+JSANCiAgZ3JvdXBfYnkoVHJlYXRtZW50KSAlPiUgDQogIHN1bW1hcmlzZShgRXN0aW1hdGVkIHByb3AuIG9mIG9mZnNwcmluZyBwcm9kdWNlZGAgPSBtZWRpYW4ocHJvcF9mb2NhbF9vZmZzcHJpbmcpLA0KICAgICAgICAgICAgYDIuNSVgID0gcXVhbnRpbGUocHJvcF9mb2NhbF9vZmZzcHJpbmcsIHByb2JzID0gMC4wMjUpLA0KICAgICAgICAgICAgYDk3LjUlYCA9IHF1YW50aWxlKHByb3BfZm9jYWxfb2Zmc3ByaW5nLCBwcm9icyA9IDAuOTc1KSkgJT4lIA0KICByZW5hbWUoYEV2b2x1dGlvbiB0cmVhdG1lbnRgID0gVHJlYXRtZW50KSAlPiUgDQogIHBhbmRlcihzcGxpdC5jZWxsID0gNDAsIHNwbGl0LnRhYmxlID0gSW5mLCByb3VuZCA9IDMpDQoNCiMgbm93IGZpbmQgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlIGNvbnRyb2wgYW5kIHRoZSBzZXgtbGltaXRlZCB0cmVhdG1lbnRzDQoNCiMgdGhlIGludl9sb2dpdF9zY2FsZWQoKSBmdW5jdGlvbiBjb252ZXJ0cyB0aGUgcG9zdGVyaW9yIGRyYXdzIG9udG8gdGhlIHJlc3BvbnNlIHNjYWxlIA0KDQogIGRyYXdzICU+JSANCiAgbXV0YXRlKHBfY29udHJvbCA9ICBpbnZfbG9naXRfc2NhbGVkKGJfSW50ZXJjZXB0KSwNCiAgICAgICAgIHBfZmVtYWxlID0gaW52X2xvZ2l0X3NjYWxlZChiX1RyZWF0bWVudEZlbWFsZV9saW1pdGVkICsgYl9JbnRlcmNlcHQpLA0KICAgICAgICAgcF9tYWxlID0gaW52X2xvZ2l0X3NjYWxlZChiX1RyZWF0bWVudE1hbGVfbGltaXRlZCArIGJfSW50ZXJjZXB0KSwNCiAgICAgICAgIGBGZW1hbGUtbGltaXRlZGAgPSBwX2ZlbWFsZSAvIHBfY29udHJvbCwNCiAgICAgICAgIGBNYWxlLWxpbWl0ZWRgID0gcF9tYWxlIC8gcF9jb250cm9sKSAlPiUgDQogIGdhdGhlcihrZXkgPSBgZGlmZmVyZW5jZSBjb21wYXJpc29uYCwgdmFsdWUgPSBgJSBkaWZmZXJlbmNlYCkgJT4lIA0KICBmaWx0ZXIoYGRpZmZlcmVuY2UgY29tcGFyaXNvbmAgPT0gYygiRmVtYWxlLWxpbWl0ZWQiLCAiTWFsZS1saW1pdGVkIikpICU+JSANCiAgZ3JvdXBfYnkoYGRpZmZlcmVuY2UgY29tcGFyaXNvbmApICAlPiUgDQogIHN1bW1hcmlzZShgTWVhbiBwcm9wb3J0aW9uIG9mIG9mZnNwcmluZyBwcm9kdWNlZCByZWxhdGl2ZSB0byBjb250cm9sYCAgPSBtZWFuKGAlIGRpZmZlcmVuY2VgKSwNCiAgICAgICAgICAgIGAyLjUlYCA9IHF1YW50aWxlKGAlIGRpZmZlcmVuY2VgLCBwcm9icyA9IDAuMDI1KSwNCiAgICAgICAgICAgIGA5Ny41JWAgPSBxdWFudGlsZShgJSBkaWZmZXJlbmNlYCwgcHJvYnMgPSAwLjk3NSkpICU+JSANCiAgcmVuYW1lKGBFdm9sdXRpb24gdHJlYXRtZW50YCA9IGBkaWZmZXJlbmNlIGNvbXBhcmlzb25gKSAlPiUgDQogIHBhbmRlcihzcGxpdC5jZWxsID0gNDAsIHNwbGl0LnRhYmxlID0gSW5mLCByb3VuZCA9IDMpDQpgYGANCg0KTGV0cyBwbG90IG91ciBmaW5kaW5ncw0KDQpgYGB7cn0NCiMgcGxvdA0KZl8xIDwtDQogIGRyYXdzX2ZlbWFsZSAlPiUgDQogIGdncGxvdChhZXMoVHJlYXRtZW50LCBwcm9wX2ZvY2FsX29mZnNwcmluZykpICsgDQogIHN0YXRfZXllKGFlcyhmaWxsID0gVHJlYXRtZW50KSwgLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAxKSArICMgd2lkdGggaW5kaWNhdGVzIHRoZSB1bmNlcnRhaW50eSBpbnRlcnZhbHM6IGhlcmUgd2UgaGF2ZSA2NiUgYW5kIDk1JSBpbnRlcnZhbHMNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMykpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJGZW1hbGUgZml0bmVzc1xuKHByb3BvcnRpb24gb2Ygb2Zmc3ByaW5nIHByb2R1Y2VkKSIsDQogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDAuNiwgMC43LCAwLjgsIDAuOSkpICsNCiAgeGxhYigiRXZvbHV0aW9uYXJ5IGhpc3RvcnkiKSArDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQ0KDQpmXzIgPC0NCiAgZHJhd3MgJT4lIA0KICBtdXRhdGUoYEZlbWFsZS1saW1pdGVkYCA9IGJfVHJlYXRtZW50RmVtYWxlX2xpbWl0ZWQsDQogICAgICAgICBgTWFsZS1saW1pdGVkYCA9IGJfVHJlYXRtZW50TWFsZV9saW1pdGVkKSAlPiUgDQogIGdhdGhlcihrZXkgPSBwYXJhbWV0ZXIsIHZhbHVlID0gbG9nb2RkcykgJT4lIA0KICBmaWx0ZXIocGFyYW1ldGVyID09IGMoIkZlbWFsZS1saW1pdGVkIiwgIk1hbGUtbGltaXRlZCIpKSAlPiUNCiAgYXNfdGliYmxlKCkgJT4lIA0KICANCiAgZ2dwbG90KGFlcyhwYXJhbWV0ZXIsIGxvZ29kZHMpKSArIA0KICBzdGF0X2hhbGZleWUoYWVzKGZpbGwgPSBwYXJhbWV0ZXIpLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpKSArICMgd2lkdGggaW5kaWNhdGVzIHRoZSB1bmNlcnRhaW50eSBpbnRlcnZhbHM6IGhlcmUgd2UgaGF2ZSA2NiUgYW5kIDk1JSBpbnRlcnZhbHMNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiRmVtYWxlLWxpbWl0ZWQiID0gIiNmZmQwNmYiLCAiTWFsZS1saW1pdGVkIiA9ICIjNzJiY2Q1IikpICsgDQogIGNvb3JkX2ZsaXAoKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMikgKw0KICAjc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoLTQsIC0yLCAwLCAyKSkgKw0KICB4bGFiKE5VTEwpICsNCiAgeWxhYigiTG9nLW9kZHMgZGlmZmVyZW5jZSBmcm9tIGNvbnRyb2wiKSArDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQ0KDQpmXzEgKyBmXzINCg0KYGBgDQoNCg0KKipGaWd1cmUgMioqOiBjaHJvbW9zb21lcyB3aXRoIHNleC1saW1pdGVkIGluaGVyaXRhbmNlIGhhdmUgaGlnaGVyIGZpdG5lc3MgaW4gZmVtYWxlcyB0aGFuIGNocm9tb3NvbWVzIHdpdGggdW5jb25zdHJhaW5lZCBpbmhlcml0YW5jZS4NCg0KJH4kDQoNCiMgTWFsZSBmaXRuZXNzDQoNCiR+JA0KDQpUbyBlc3RpbWF0ZSB0aGUgZml0bmVzcyBvZiBtYWxlcyBjYXJyeWluZyBlYWNoIG9mIHRoZSB0aHJlZSBjaHJvbW9zb21lIHR5cGVzLCB3ZSBjb25kdWN0ZWQgYW4gZXhwZXJpbWVudCB2ZXJ5IHNpbWlsYXIgdG8gdGhlIGZlbWFsZSBmaXRuZXNzIGFzc2F5LiBIb3dldmVyLCBiZWNhdXNlIG1hbGUgZml0bmVzcyBoYXMgc3Ryb25nZXIgY292YXJpYW5jZSB3aXRoIGZlcnRpbGlzYXRpb24gZXZlbnRzIHRoYW4gZG9lcyBmZW1hbGUgZml0bmVzcywgd2UgY29uZHVjdGVkIHRoZSBtYWxlIGZpdG5lc3MgYXNzYXkgd2l0aCBhIDE6MiBzZXggcmF0aW8gKGZlbWFsZTptYWxlKSByYXRoZXIgdGhhbiB0aGUgMToxIHJhdGlvIHVzZWQgaW4gdGhlIGZlbWFsZSBhc3NheS4gVGhpcyBpbmNyZWFzZXMgdGhlIHN0cmVuZ3RoIG9mIHNleHVhbCBzZWxlY3Rpb24gYW5kIGlzIGEgbW9yZSBhcHBvcHJpYXRlIHdheSB0byBleHBvc2UgZGlmZmVyZW5jZXMgaW4gZml0bmVzcyBiZXR3ZWVuIGdyb3VwcyBvZiBtYWxlcy4gQXMgd2l0aCB0aGUgZmVtYWxlcywgd2UgY2FsY3VsYXRlZCBmaXRuZXNzIGFzIHRoZSBwcm9wb3J0aW9uIG9mIHJlZCBleWVkIG9mZnNwcmluZyBpbiB0aGUgdmlhbC4gDQoNCiR+JA0KDQpMZXQncyBvbmNlIGFnYWluIHN0YXJ0IHdpdGggYSBzaW1wbGUgbW9kZWwuIFdlJ2xsIHNwZWNpZnkgdGhlIGJpbm9taWFsIGZhbWlseSwgc2V0IHByaW9ycyBhbmQgaW5jbHVkZSBgUmVhcmluZ192aWFsYCBhcyBhIHJhbmRvbSBlZmZlY3QsIGp1c3QgYXMgd2UgZGlkIGZvciB0aGUgZmVtYWxlIGRhdGEuDQoNCmBgYHtyfQ0KbWFsZV9maXRuZXNzLjAxIDwtDQogIGJybShUb3RhbF9yZWRfb2Zmc3ByaW5nIHwgdHJpYWxzKFRvdGFsX29mZnNwcmluZykgfiAxICsgKDF8UmVhcmluZ192aWFsKSwNCiAgICAgIGRhdGEgPSBtYWxlX2ZpdG5lc3MsIGZhbWlseSA9IGJpbm9taWFsKCksIA0KICAgICAgcHJpb3IgPSBjKHByaW9yKG5vcm1hbCgwLCAxLjUpLCBjbGFzcyA9IEludGVyY2VwdCksDQogICAgICAgICAgICAgICAgI3ByaW9yKG5vcm1hbCgwLCAyKSwgY2xhc3MgPSBiKSwNCiAgICAgICAgICAgICAgICBwcmlvcihleHBvbmVudGlhbCgxKSwgY2xhc3MgPSBzZCkpLA0KICAgICAgaXRlciA9IDEwMDAwLCB3YXJtdXAgPSAyMDAwLCBjaGFpbnMgPSA0LCBjb3JlcyA9IDQsDQogICAgICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOTUsIG1heF90cmVlZGVwdGggPSAxMCksDQogICAgICBzZWVkID0gMiwgZmlsZSA9ICJGaXRzL21hbGVfZml0bmVzcy4wMSIpDQoNCiNhZGRfY3JpdGVyaW9uKG1hbGVfZml0bmVzcy4wMSwgY3JpdGVyaW9uID0gIndhaWMiKQ0KDQpgYGANCg0KQ29uZHVjdCB0aGUgcG9zdGVyaW9yIHByZWRpY3RpdmUgY2hlY2suLi4NCg0KYGBge3J9DQpwcF9jaGVjayhtYWxlX2ZpdG5lc3MuMDEsIHR5cGUgPSAiaGlzdCIsIG5kcmF3cyA9IDExLCBiaW53aWR0aCA9IDEwKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCkpDQpgYGANCg0KTm93IHdlIGNhbiB2aXN1YWxpc2Ugb3VyIHByZWRpY3Rpb25zIGZvciBlYWNoIHJlYXJpbmcgdmlhbC4NCg0KYGBge3J9DQojIGdldCBkcmF3cyBmcm9tIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uDQoNCmRyYXdzX20gPC0gYXNfZHJhd3NfZGYobWFsZV9maXRuZXNzLjAxKQ0KDQojIHdyYW5nbGUgdGhlIGRhdGEgdG8gZ2V0IHJlbGV2YW50IHByZWRpY3Rpb25zDQoNCmRyYXdzX3JlYXJpbmdfdmlhbHNfbSA8LSANCiAgY29lZihtYWxlX2ZpdG5lc3MuMDEsIHJvYnVzdCA9IFQpJFJlYXJpbmdfdmlhbFssICwgXSAlPiUgDQogIGFzX3RpYmJsZShyb3duYW1lcyA9IE5BKSAlPiUgDQogIHJvd25hbWVzX3RvX2NvbHVtbigiUmVhcmluZ192aWFsIikgJT4lIA0KICBtdXRhdGUoRXN0aW1hdGUgPSBpbnZfbG9naXRfc2NhbGVkKEVzdGltYXRlKSwNCiAgICAgICAgIFEyLjUgPSBpbnZfbG9naXRfc2NhbGVkKFEyLjUpLA0KICAgICAgICAgUTk3LjUgPSBpbnZfbG9naXRfc2NhbGVkKFE5Ny41KSkgJT4lIA0KICBzZWxlY3QoUmVhcmluZ192aWFsLCBFc3RpbWF0ZSwgUTIuNSwgUTk3LjUpICU+JSANCiAgbXV0YXRlX2F0KDI6NCwgcm91bmQsIDMpDQoNCiMgY29tYmluZSB3aXRoIHJhdyBkYXRhIA0KDQpkcmF3c19yZWFyaW5nX3ZpYWxzX20gPC0NCiAgZnVsbF9qb2luKGRyYXdzX3JlYXJpbmdfdmlhbHNfbSwgbWFsZV9maXRuZXNzICU+JSBkaXN0aW5jdChSZWFyaW5nX3ZpYWwsIC5rZWVwX2FsbCA9IFRSVUUpICU+JSANCiAgc2VsZWN0KEJsb2NrLCBQb3B1bGF0aW9uLCBUcmVhdG1lbnQsIEdGUCwgUmVhcmluZ192aWFsKSkNCg0KIyBwbG90IHRoZSB2YXJpYXRpb24gYmV0d2VlbiByZWFyaW5nIHZpYWxzIGZvciBmaXRuZXNzLCBpbmNsdWRpbmcgYmxvY2sgYW5kIEdGUCBlZmZlY3RzIA0KDQpkcmF3c19yZWFyaW5nX3ZpYWxzX20gJT4lIA0KICBtdXRhdGUoUmVhcmluZ192aWFsID0gYXMubnVtZXJpYyhSZWFyaW5nX3ZpYWwpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IFJlYXJpbmdfdmlhbCkpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gaW52X2xvZ2l0X3NjYWxlZChtZWRpYW4oZHJhd3MkYl9JbnRlcmNlcHQpKSwgbGluZXR5cGUgPSAyLCBzaXplID0gMS8yKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGMoMjQuNSwgNDguNSksIHNpemUgPSAxLzMsIGNvbG9yID0gImdyZXkyNSIpICsNCiAgZ2VvbV9wb2ludChhZXMoeSA9IEVzdGltYXRlLCBmaWxsID0gR0ZQKSwgc2hhcGUgPSAyMSwgc2l6ZSA9IDMpICsNCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgDQogICAgICAgICAgIHggPSBjKDEyLCAzNiwgNjApLCB5ID0gMC40LCANCiAgICAgICAgICAgbGFiZWwgPSBjKCJCbG9jayAxIiwgIkJsb2NrIDIiLCAiQmxvY2sgMyIpKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJncmV5IiwgImdyZWVuIikpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IE5VTEwpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMC41LCAwLjc1LCAxKSwgbGltaXRzID0gYygwLjM1LCAxKSkgKw0KICBsYWJzKHkgPSAiRml0bmVzcyIsDQogICAgICAgeCA9IE5VTEwpICsNCiAgdGhlbWVfYncoKSArDQogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCkpDQpgYGANCg0KDQpXaGV0aGVyIHRoZXJlIGlzIGEgZGlmZmVyZW5jZSBpbiBmaXRuZXNzIGJldHdlZW4gdGhlIHR3byBHRlAgdHJhbnNnZW5lcyBpcyBub3QgYXMgY2xlYXIgdGhpcyB0aW1lLiBIb3dldmVyLCB3ZSBvbmNlIGFnYWluIHNlZSBkaWZmZXJlbmNlcyBpbiBmaXRuZXNzIGJldHdlZW4gQmxvY2tzLCB3aXRoIEJsb2NrIDIgbG9va2luZyB0byBoYXZlIGhpZ2hlciBmaXRuZXNzIG1lYXN1cmVzIHRoYW4gMSBvciAzLg0KDQokfiQNCg0KKipUaGUgZnVsbCBtb2RlbCoqDQoNCk5vdyBsZXRzIGFkZCBpbiB0aGUgZml4ZWQgZWZmZWN0czoNCg0KLSBUcmVhdG1lbnQNCg0KLSBHRlANCg0KLSBCbG9jaw0KDQpUaGUgbW9kZWwgYmVsb3cgaXMgZ29vZCwgYnV0IGl0J3MgbWlzc2luZyB0aGUgYFBvcHVsYXRpb25gIHZhcmlhYmxlLg0KDQpgYGB7cn0NCm1hbGVfZml0bmVzcy4wMiA8LQ0KICBicm0oVG90YWxfcmVkX29mZnNwcmluZyB8IHRyaWFscyhUb3RhbF9vZmZzcHJpbmcpIH4gMSArIFRyZWF0bWVudCArIEdGUCArIEJsb2NrICsgKDF8UmVhcmluZ192aWFsKSwNCiAgICAgIGRhdGEgPSBtYWxlX2ZpdG5lc3MsIGZhbWlseSA9IGJpbm9taWFsKCksIA0KICAgICAgcHJpb3IgPSBjKHByaW9yKG5vcm1hbCgwLCAxLjUpLCBjbGFzcyA9IEludGVyY2VwdCksDQogICAgICAgICAgICAgICAgcHJpb3Iobm9ybWFsKDAsIDIpLCBjbGFzcyA9IGIpLA0KICAgICAgICAgICAgICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9IHNkKSksDQogICAgICBpdGVyID0gMTAwMDAsIHdhcm11cCA9IDIwMDAsIGNoYWlucyA9IDQsIGNvcmVzID0gNCwNCiAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45NSwgbWF4X3RyZWVkZXB0aCA9IDEwKSwNCiAgICAgIHNlZWQgPSAyLCBmaWxlID0gIkZpdHMvbWFsZV9maXRuZXNzLjAyIikNCg0KI2FkZF9jcml0ZXJpb24obWFsZV9maXRuZXNzLjAyLCBjcml0ZXJpb24gPSAid2FpYyIpDQoNCnByaW50KG1hbGVfZml0bmVzcy4wMikNCmBgYA0KDQpUaGlzIHRpbWUsIHdlIGhhdmUgZXZpZGVuY2UgdG8gc3VnZ2VzdCB0aGF0IG1hbGUtYWRhcHRlZCBjaHJvbW9zb21lcyBwcm9kdWNlIGhpZ2ggZml0bmVzcyBtYWxlcywgYnV0IHRoYXQgZmVtYWxlLWFkYXB0dGVkIGNocm9tb3NvbWVzIHByb2R1Y2UgbWFsZXMgd2l0aCB0aGUgc2FtZSBmaXRuZXNzIGFzIGRvIGNvbnRyb2wgY2hyb21vc29tZXMuDQoNCiR+JA0KDQpHZXQgcHJlZGljdGlvbnMgZnJvbSB0aGUgbW9kZWwgYW5kIHByZXNlbnQgdGhlbSBpbiBhIFRhYmxlDQoNCmBgYHtyfQ0KDQpkcmF3c19tIDwtIGFzX2RyYXdzX2RmKG1hbGVfZml0bmVzcy4wMikNCg0KZHJhd3NfbWFsZSA8LQ0KICBkcmF3c19tICAlPiUgDQogIG11dGF0ZShgRmVtYWxlLWxpbWl0ZWRgID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCArIGJfVHJlYXRtZW50RmVtYWxlX2xpbWl0ZWQpLA0KICAgICAgICAgYE1hbGUtbGltaXRlZGAgPSBpbnZfbG9naXRfc2NhbGVkKGJfSW50ZXJjZXB0ICsgYl9UcmVhdG1lbnRNYWxlX2xpbWl0ZWQpLA0KICAgICAgICAgQ29udHJvbCA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQpKSAlPiUgDQogIHNlbGVjdChDb250cm9sLCBgRmVtYWxlLWxpbWl0ZWRgLCBgTWFsZS1saW1pdGVkYCkgJT4lIA0KICAgIHBpdm90X2xvbmdlcihjb2xzID0gYyhDb250cm9sLCBgRmVtYWxlLWxpbWl0ZWRgLCBgTWFsZS1saW1pdGVkYCksDQogICAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIlRyZWF0bWVudCIpICU+JSANCiAgcmVuYW1lKHByb3BfZm9jYWxfb2Zmc3ByaW5nID0gdmFsdWUpDQoNCmRyYXdzX21hbGUgJT4lIA0KICBncm91cF9ieShUcmVhdG1lbnQpICU+JSANCiAgc3VtbWFyaXNlKGBFc3RpbWF0ZWQgcHJvcC4gb2Ygb2Zmc3ByaW5nIHNpcmVkYCA9IG1lZGlhbihwcm9wX2ZvY2FsX29mZnNwcmluZyksDQogICAgICAgICAgICBgMi41JWAgPSBxdWFudGlsZShwcm9wX2ZvY2FsX29mZnNwcmluZywgcHJvYnMgPSAwLjAyNSksDQogICAgICAgICAgICBgOTcuNSVgID0gcXVhbnRpbGUocHJvcF9mb2NhbF9vZmZzcHJpbmcsIHByb2JzID0gMC45NzUpKSAlPiUgDQogIHJlbmFtZShgRXZvbHV0aW9uIHRyZWF0bWVudGAgPSBUcmVhdG1lbnQpICU+JSANCiAgcGFuZGVyKHNwbGl0LmNlbGwgPSA0MCwgc3BsaXQudGFibGUgPSBJbmYsIHJvdW5kID0gMykNCg0KIyBub3cgZmluZCB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGUgY29udHJvbCBhbmQgdGhlIHNleC1saW1pdGVkIHRyZWF0bWVudHMNCg0KIyB0aGUgaW52X2xvZ2l0X3NjYWxlZCgpIGZ1bmN0aW9uIGNvbnZlcnRzIHRoZSBwb3N0ZXJpb3IgZHJhd3Mgb250byB0aGUgcmVzcG9uc2Ugc2NhbGUgDQoNCiAgZHJhd3NfbSAlPiUgDQogIG11dGF0ZShwX2NvbnRyb2wgPSAgaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCksDQogICAgICAgICBwX2ZlbWFsZSA9IGludl9sb2dpdF9zY2FsZWQoYl9UcmVhdG1lbnRGZW1hbGVfbGltaXRlZCArIGJfSW50ZXJjZXB0KSwNCiAgICAgICAgIHBfbWFsZSA9IGludl9sb2dpdF9zY2FsZWQoYl9UcmVhdG1lbnRNYWxlX2xpbWl0ZWQgKyBiX0ludGVyY2VwdCksDQogICAgICAgICBgRmVtYWxlLWxpbWl0ZWRgID0gcF9mZW1hbGUgLyBwX2NvbnRyb2wsDQogICAgICAgICBgTWFsZS1saW1pdGVkYCA9IHBfbWFsZSAvIHBfY29udHJvbCkgJT4lIA0KICBnYXRoZXIoa2V5ID0gYGRpZmZlcmVuY2UgY29tcGFyaXNvbmAsIHZhbHVlID0gYCUgZGlmZmVyZW5jZWApICU+JSANCiAgZmlsdGVyKGBkaWZmZXJlbmNlIGNvbXBhcmlzb25gID09IGMoIkZlbWFsZS1saW1pdGVkIiwgIk1hbGUtbGltaXRlZCIpKSAlPiUgDQogIGdyb3VwX2J5KGBkaWZmZXJlbmNlIGNvbXBhcmlzb25gKSAgJT4lIA0KICBzdW1tYXJpc2UoYE1lYW4gcHJvcG9ydGlvbiBvZiBvZmZzcHJpbmcgc2lyZWQgcmVsYXRpdmUgdG8gY29udHJvbGAgID0gbWVhbihgJSBkaWZmZXJlbmNlYCksDQogICAgICAgICAgICBgMi41JWAgPSBxdWFudGlsZShgJSBkaWZmZXJlbmNlYCwgcHJvYnMgPSAwLjAyNSksDQogICAgICAgICAgICBgOTcuNSVgID0gcXVhbnRpbGUoYCUgZGlmZmVyZW5jZWAsIHByb2JzID0gMC45NzUpKSAlPiUgDQogIHJlbmFtZShgRXZvbHV0aW9uIHRyZWF0bWVudGAgPSBgZGlmZmVyZW5jZSBjb21wYXJpc29uYCkgJT4lIA0KICBwYW5kZXIoc3BsaXQuY2VsbCA9IDQwLCBzcGxpdC50YWJsZSA9IEluZiwgcm91bmQgPSAzKQ0KYGBgDQoNCkxldHMgcGxvdCBvdXIgZmluZGluZ3MNCg0KYGBge3J9DQojIHBsb3QNCmZfMyA8LQ0KICBkcmF3c19tYWxlICU+JSANCiAgZ2dwbG90KGFlcyhUcmVhdG1lbnQsIHByb3BfZm9jYWxfb2Zmc3ByaW5nKSkgKyANCiAgc3RhdF9leWUoYWVzKGZpbGwgPSBUcmVhdG1lbnQpLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDEpICsgIyB3aWR0aCBpbmRpY2F0ZXMgdGhlIHVuY2VydGFpbnR5IGludGVydmFsczogaGVyZSB3ZSBoYXZlIDY2JSBhbmQgOTUlIGludGVydmFscw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAzKSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIk1hbGUgZml0bmVzc1xuKHByb3BvcnRpb24gb2Ygb2Zmc3ByaW5nIHNpcmVkKSIsDQogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDAuNiwgMC43LCAwLjgsIDAuOSkpICsNCiAgeGxhYigiRXZvbHV0aW9uYXJ5IGhpc3RvcnkiKSArDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCB2anVzdCA9IDEsIGhqdXN0PTEpKQ0KDQpmXzQgPC0NCiAgZHJhd3NfbSAlPiUgDQogIG11dGF0ZShgRmVtYWxlLWxpbWl0ZWRgID0gYl9UcmVhdG1lbnRGZW1hbGVfbGltaXRlZCwNCiAgICAgICAgIGBNYWxlLWxpbWl0ZWRgID0gYl9UcmVhdG1lbnRNYWxlX2xpbWl0ZWQpICU+JSANCiAgZ2F0aGVyKGtleSA9IHBhcmFtZXRlciwgdmFsdWUgPSBsb2dvZGRzKSAlPiUgDQogIGZpbHRlcihwYXJhbWV0ZXIgPT0gYygiRmVtYWxlLWxpbWl0ZWQiLCAiTWFsZS1saW1pdGVkIikpICU+JQ0KICBhc190aWJibGUoKSAlPiUgDQogICNtdXRhdGUocGFyYW1ldGVyID1mYWN0b3IocGFyYW1ldGVyLCBsZXZlbHM9YygiU0QtTWFkIiwgIlNELTcyIiwgIlNELTUiKSkpICU+JQ0KICANCiAgZ2dwbG90KGFlcyhwYXJhbWV0ZXIsIGxvZ29kZHMpKSArIA0KICBzdGF0X2hhbGZleWUoYWVzKGZpbGwgPSBwYXJhbWV0ZXIpLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpKSArICMgd2lkdGggaW5kaWNhdGVzIHRoZSB1bmNlcnRhaW50eSBpbnRlcnZhbHM6IGhlcmUgd2UgaGF2ZSA2NiUgYW5kIDk1JSBpbnRlcnZhbHMNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiRmVtYWxlLWxpbWl0ZWQiID0gIiNmZmQwNmYiLCAiTWFsZS1saW1pdGVkIiA9ICIjNzJiY2Q1IikpICsgDQogIGNvb3JkX2ZsaXAoKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMikgKw0KICAjc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoLTQsIC0yLCAwLCAyKSkgKw0KICB4bGFiKE5VTEwpICsNCiAgeWxhYigiTG9nLW9kZHMgZGlmZmVyZW5jZSBmcm9tIGNvbnRyb2wiKSArDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQ0KDQpmXzMgKyBmXzQNCg0KYGBgDQoNCg0KKipGaWd1cmUgMyoqOiBjaHJvbW9zb21lcyB3aXRoIG1hbGUtbGltaXRlZCBpbmhlcml0YW5jZSBoYXZlIGhpZ2hlciBmaXRuZXNzIGluIG1hbGVzIHRoYW4gY2hyb21vc29tZXMgd2l0aCB1bmNvbnN0cmFpbmVkIG9yIGZlbWFsZS1saW1pdGVkIGluaGVyaXRhbmNlLg0K